package View;

import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.*;
import java.util.ListIterator;
import java.util.Observable;
import java.util.Observer;

import javax.swing.*;

import Controller.ButtonHandler;
import Controller.MenuHandler;
import Model.*;

/*
* Displays and updates its graphical view for a given game
* -Commented(Apr 4,2011)
* Samual Martelli
* </pre>
*/
public class GraphicalView implements Observer {

	public static final String PACMAN = "New Pacman Game";
	public static final String MOUSE = "New Mouseland Game";
	public static final String BUNNY = "New FriskyBunny Game";
	public static final String RESET = "Reset Current Game";

	private JFrame gameFrame = new JFrame("Flummox: Puzzle Game Engine");
	private GameButton[][] buttons = new GameButton[Maze.MAP_SIZE][Maze.MAP_SIZE];
	public static final ImageIcon wallIcon = new ImageIcon(
			"doc/resources/wall.jpg");
	public static final ImageIcon noIcon = new ImageIcon("doc/resources/no.jpg");

	// pacman specific
	public static final ImageIcon ghostIcon = new ImageIcon(
			"doc/resources/ghost.jpg");
	public static final ImageIcon pacIcon = new ImageIcon(
			"doc/resources/pacman.jpg");
	public static final ImageIcon portalIcon = new ImageIcon(
			"doc/resources/portal.jpg");
	public static final ImageIcon dotIcon = new ImageIcon(
			"doc/resources/dot.jpg");
	// mouseland specific
	public static final ImageIcon timIcon = new ImageIcon(
			"doc/resources/tinyTim.jpg");
	public static final ImageIcon ratIcon = new ImageIcon(
			"doc/resources/rat.jpg");
	public static final ImageIcon ratTunnelIcon = new ImageIcon(
			"doc/resources/ratTunnel.jpg");
	public static final ImageIcon trapIcon = new ImageIcon(
			"doc/resources/catTrap.jpg");
	public static final ImageIcon exitIcon = new ImageIcon(
			"doc/resources/exit.jpg");
	// frisky bunny specific
	public static final ImageIcon friskyIcon = new ImageIcon(
			"doc/resources/friskyBunny.jpg");
	public static final ImageIcon runIcon = new ImageIcon(
			"doc/resources/runningBunny.jpg");
	public static final ImageIcon foxIcon = new ImageIcon(
			"doc/resources/fox.jpg");
	public static final ImageIcon hedgeIcon = new ImageIcon(
			"doc/resources/hedge.jpg");

	private JMenuBar bar;
	private JMenu gameMenu;

	private JMenuItem new1;
	private JMenuItem new2;
	private JMenuItem new3;
	private JMenuItem reset;

	public GraphicalView() {
		// handle each menu item

		new1 = new JMenuItem(PACMAN);
		new2 = new JMenuItem(MOUSE);
		new3 = new JMenuItem(BUNNY);
		reset = new JMenuItem(RESET);

		MenuHandler new1Handle = new MenuHandler(new1, this);
		MenuHandler new2Handle = new MenuHandler(new2, this);
		MenuHandler new3Handle = new MenuHandler(new3, this);
		MenuHandler resetHandle = new MenuHandler(reset, this);

		bar = new JMenuBar();
		gameMenu = new JMenu("Game");
		gameMenu.setMnemonic(KeyEvent.VK_G);// g opens the game menu
		gameMenu.getAccessibleContext().setAccessibleDescription(
				"This menu is for starting a new game,resetting "
						+ "current game or  exitting the Flummox game room");
		bar.add(gameMenu);

		new1.addActionListener(new1Handle);
		new1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1,
				ActionEvent.ALT_MASK));
		new1.getAccessibleContext().setAccessibleDescription(
				"Starts a game of pacman");
		gameMenu.add(new1);

		new2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_2,
				ActionEvent.ALT_MASK));
		new2.getAccessibleContext().setAccessibleDescription(
				"Starts a game of escape to mouseland");
		new2.addActionListener(new2Handle);
		gameMenu.add(new2);

		new3.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_3,
				ActionEvent.ALT_MASK));
		new3.getAccessibleContext().setAccessibleDescription(
				"Starts a game of frisky bunny");
		new3.addActionListener(new3Handle);
		gameMenu.add(new3);

		reset.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
				ActionEvent.ALT_MASK));
		reset.getAccessibleContext().setAccessibleDescription(
				"Restarts current game");
		reset.addActionListener(new1Handle);
		gameMenu.add(reset);

		gameFrame.setJMenuBar(bar);

		// Set the layout according to the layout of maze and its size
		gameFrame.getContentPane().setLayout(
				new GridLayout(Maze.MAP_SIZE, Maze.MAP_SIZE));
		// Add the components, set the icons accordingly and resize if needed
		for (int y = 0; y < Maze.MAP_SIZE; y++) {
			for (int x = 0; x < Maze.MAP_SIZE; x++) {
				GameButton button = new GameButton(x, y);
				buttons[x][y] = button;
				gameFrame.getContentPane().add(button);

			}

		}
		gameFrame.setSize(200, 200);
		gameFrame.setVisible(true);
		gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	
	/**
	 * The standard update called immediately following a notify -added comment
	 * (Mar 15,2011) Samual Martelli </pre>
	 * @param arg 
	 */
	public void updateMaze(GameCharacter curChar, Point arg) {

			

		for (int i = 0; i < Maze.MAP_SIZE; i++) {
			for (int j = 0; j < Maze.MAP_SIZE; j++) {
				// space is a player
				Point here = new Point(i, j);
				if (here.equals(curChar.getCoordinate())) {
					if (curChar instanceof PacMan) {
						changeButtonIcon(arg.x,arg.y,GraphicalView.noIcon);
						changeButtonIcon(here.x, here.y, GraphicalView.pacIcon);
					} else if (curChar instanceof Ghost) {
						changeButtonIcon(here.x, here.y,
								GraphicalView.ghostIcon);
					} else if (curChar instanceof Fox) {
						changeButtonIcon(here.x, here.y, GraphicalView.foxIcon);
					} else if (curChar instanceof RunningBunny) {
						changeButtonIcon(here.x, here.y, GraphicalView.runIcon);
					} else if (curChar instanceof FriskyBunny) {
						changeButtonIcon(arg.x,arg.y,GraphicalView.noIcon);
						changeButtonIcon(here.x, here.y,
								GraphicalView.friskyIcon);
					} else if (curChar instanceof Rat) {
						changeButtonIcon(here.x, here.y, GraphicalView.ratIcon);
					} else if (curChar instanceof TinyTim) {
						changeButtonIcon(arg.x,arg.y,GraphicalView.noIcon);
						changeButtonIcon(here.x, here.y, GraphicalView.timIcon);
					}

				}
				

			}
		}
	}

	// when the model changes the controller calls toString on Maze
	@Override
	public void update(Observable o, Object arg) {
		
		if (o instanceof GameCharacter) {
			updateMaze((GameCharacter) o,(Point) arg);
		}

	}

	public GameButton getButton(int x, int y) {
		return buttons[x][y];
	}

	public void changeButtonIcon(int x, int y, ImageIcon newIcon) {
		buttons[x][y].setIcon(newIcon);
	}
	
	public  void gameOverMessage(){
		JOptionPane.showMessageDialog(gameFrame,"Your Game has ended!","Game Over",JOptionPane.PLAIN_MESSAGE);
	}

}
